package com.soa.zuul.filter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.soa.zuul.entity.GatewayHttpApi;
import com.soa.zuul.entity.GatewayService;
import com.soa.zuul.service.AppLimitService;
import com.soa.zuul.service.FeignLogService;
import com.soa.zuul.util.CodeMsg;
import com.soa.zuul.util.Json;
import com.soa.zuul.util.RequestUtil;

/**
 * 基于应用的限流
 * @author zheng
 *
 */
public class AppLimitFilter extends ZuulFilter {
	public final static Logger logger = LoggerFactory.getLogger(AppLimitFilter.class);
	AppLimitService appLimitService;
	FeignLogService feignLogService;
	public AppLimitFilter(AppLimitService appLimitService,FeignLogService feignLogService) {
		this.appLimitService= appLimitService;
		this.feignLogService =feignLogService;
	}

	/**
	 * 过滤器的具体逻辑
	 *
	 * 通过ctx.setSendZuulResponse(false)令zuul过滤该请求，不对其进行路由，
	 * 通过ctx.setResponseStatusCode(401)设置了其返回的错误码
	 * 通过ctx.setResponseBody(body)对返回body内容进行编辑等。
	 * 中文乱码：ctx.getResponse().setContentType("text/html;charset=UTF-8");
	 * 
	 * @return
	 */
	@Override
	public Object run() {
		RequestContext ctx = RequestContext.getCurrentContext();
		CodeMsg codeMsg = CodeMsg.SUCCESS;
		GatewayHttpApi gatewayHttpApi=(GatewayHttpApi)ctx.get("gatewayHttpApi");
		if(gatewayHttpApi!=null){
			codeMsg  = appLimitService.getLimit(gatewayHttpApi);
			if(codeMsg.getResultcode()!=CodeMsg.SUCCESS.getResultcode()){
				feignLogService.writeLog(Json.GSON.toJson(RequestUtil.SendZuulResponseError(codeMsg, ctx))) ;
				return null;
			}
		}
		return null;
	}

	/**
	 * 返回一个boolean类型来判断该过滤器是否要执行，返回true，则过滤器生效
	 * 
	 * @return
	 */
	@Override
	public boolean shouldFilter() {
		 RequestContext ctx = RequestContext.getCurrentContext();
		 if(ctx.get("isSuccess")==null) return false;
		 return (boolean) ctx.get("isSuccess");//
	}


	@Override
	public int filterOrder() {
		return 50; // 过滤器的优先级
	}

	/**
	 * 返回一个字符串代表过滤器的类型，在zuul中定义了四种不同生命周期的过滤器类型，具体如下： pre：可以在请求被路由之前调用
	 * routing：在路由请求时候被调用 post：在routing和error过滤器之后被调用 error：处理请求时发生错误时被调用
	 * 
	 * @return
	 */
	@Override
	public String filterType() {
		return "pre";
	}

}
